今天要來介紹一個非常重要的結構:Binary Tree。昨天說到,他可以最大化減少 Linking space 的浪費問題
二元樹的定義為:
可為空樹,若非空樹,則:
答案是:二元樹不是樹!二元樹雖然有樹的結構特徵,但與一般的樹有顯著差異。
我們用個比較表來說明:
/ | Tree | Binary Tree |
---|---|---|
能否為空 | 不可為空 | 可為空 |
節點分支度(Node's degree) | >= 0 | 介於 0 ~ 2之間 |
子樹之方向性 | 無方向性 | 有方向性(左、右子樹) |
因此嚴格上來說:二元樹並不是樹。
每個節點皆只有左子樹(left skewed tree),或只有右子樹(right skewed tree)
這個結構相當重要,到後面的高等樹還會常常看到他。
Complete Binary Tree 的定義為:不同 level 由上而下生長,同個 level 是由左至右生長
來看個圖片:
可以看到在同一個 level 中,是從左邊往右邊長,並且一個 level 長完才長到下一個 level。
如果將每個節點編號的話,root 編 1 號。則:
以上面那棵樹為例:A 為 1 號,B 為 A 之左子點,編號:2 * 1 = 2
如果此樹的高度為 H,則此樹擁有這個高度可能的所有節點。
嚴格二元樹指,所有的節點 degree 皆為 0 或 2
也就是說:非樹葉節點的分支度皆為 2
不過有些版本是將它稱為 Full Binary Tree。
前兩個定理皆跟 Full Binary Tree 相關,可以參考剛剛的圖
可以利用數學歸納法來證明:
那如果是level i 的最少節點數呢?
不用想吧,就是 1。
一樣利用數學歸納法來證明:
如果是高度為 H 的節點總數最少值呢?答案就是 H。每個 level 只有一顆節點,也就是 Skewed Tree。
這個定理的證明相當有趣。
假設 N 為節點總數,再另 N1 為分支度為 1 的節點個數。
則推導出:N = N0 + N1 + N2
再來 另 B 為樹的分支總數,或稱為鏈結總數。
則可以推導出兩式:
整理上面式子:(N0 + N1 + N2) - 1 = N1 + 2 * N2
即可得出 N0 = N2 + 1
分成兩個 case:
優點:容易存取父點(因為 Array 的 Random Access 特性),且若樹為完整二元樹,不會浪費空間。
缺點:因 Array 需固定長度,增刪節點較困難。若樹為 skewed tree,則很浪費空間(2^H - 1 - H 格)
定義節點結構:一格放 data,一格放指標指向 left child 節點,再一格放指標指向 right child 節點
優點:若樹為斜曲,則較 Array 不浪費空間。增刪節點也較方便。
缺點:parent 難存取(使用的是單向鏈結)。平均來說較浪費空間(浪費 N + 1 個 link)
若樹為完整二元樹(如:heap),我們會使用 Array 來表示二元樹,其他狀況基本上都是使用 Linked List 法。
今天介紹了二元樹還有定理。明天我們要來看二元樹的走訪,以及好久不見的遞迴如何用在二元樹的操作上!
參考資料:
- https://www.geeksforgeeks.org/skewed-binary-tree/
- https://www.geeksforgeeks.org/complete-binary-tree/
- https://www.geeksforgeeks.org/perfect-binary-tree/
- https://faculty.cs.niu.edu/~mcmahon/CS241/Notes/Data_Structures/binary_trees.html#:~:text=If%20every%20non-leaf%20node,always%20contains%202N%20-%201%20nodes.